package com.zy.business.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zy.business.domain.*;
import com.zy.business.domain.vo.AbsenceDto;
import com.zy.business.mapper.*;
import com.zy.business.service.AbsenceService;
import com.zy.business.service.ShiftService;
import com.zy.common.core.domain.AjaxResult;
import com.zy.common.core.domain.entity.SysUser;
import com.zy.common.utils.DateUtil;
import com.zy.common.utils.SecurityUtils;
import com.zy.common.utils.WebUtil;
import com.zy.system.mapper.SysDictDataMapper;
import com.zy.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @description: 请假管理 服务层实现
 * @author: whf
 * @create: 2022-07-30 16:46
 **/
@Service
public class AbsenceServiceImpl extends ServiceImpl<AbsenceMapper, TbAbsence> implements AbsenceService {

    @Autowired
    private ISysUserService userService;

    @Autowired
    private PunchCardMapper punchCardMapper;

    @Autowired
    private AttendanceMapper attendanceMapper;

    @Value("${APPID}")
    private String APPID;

    @Value("${APPSECRET}")
    private String APPSECRET;

    @Value("${ABSENCE_APPLY}")
    private String applyTemplateId;

    @Value("${ABSENCE_RESULT}")
    private String resultTemplateId;

    @Value("${REPORT_BACK_APPLY}")
    private String reportBackApply;

    @Value("${REPORT_BACK_RESULT}")
    private String reportBackResult;

    @Autowired
    private SysDictDataMapper dictMapper;

    @Autowired
    private HolidayMapper holidayMapper;

    @Autowired
    private ShiftService shiftService;

    @Autowired
    private ReportBackMapper reportBackMapper;

    @Autowired
    private AbsenceAuditMapper absenceAuditMapper;

    /**
     * 添加请假申请
     * @param absence
     * @return
     */
    @Transactional
    public AjaxResult add(TbAbsence absence){
        List<TbAbsence> absenceList = baseMapper.selectList(new QueryWrapper<TbAbsence>().eq("apply_id", absence.getApplyId()).eq("state", 1));
        if (absenceList!=null && absenceList.size()>0){
            return AjaxResult.error(503,"有待审核的请假申请,请勿重复提交！");
        }
        absence.setState(1);
        absence.setCreateTime(new Date());
        absence.setActualAbsence(absence.getAbsenceDuration()-absence.getSabbaticalHour());
        absence.setActualSabbatical(absence.getSabbaticalHour());
        this.save(absence);
        TbAbsenceAudit audit = new TbAbsenceAudit();
        audit.setAbsenceId(absence.getAbsenceId());
        audit.setApproveId(absence.getApproveId());
        audit.setCreateBy(SecurityUtils.getUsername());
        audit.setCreateTime(new Date());
        absenceAuditMapper.insert(audit);
        this.sendMessage(absence,absence.getApproveId(),1);
        return AjaxResult.success();
    }

    @Override
    public void sendMessage(TbAbsence absence,Long approveId, Integer type){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        SysUser applyUser = userService.selectUserById(absence.getApplyId());
        SysUser auditUser = null;
        if (approveId!=null){
            auditUser = userService.selectUserById(approveId);
        }else{
            auditUser = userService.selectUserById(absence.getApproveId());
        }
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        String templtId = "";
        String toUser = "";
        String remarkStr = "";
        String color = "#173177";
        String firstStr = "";
        String keyStr1 = "";
        String keyStr2 = sdf.format(absence.getStartTime());
        String keyStr3 = sdf.format(absence.getEndTime());
        String keyStr4 = "";
        String typeStr = "";
        //申请提醒
        if (type==1){
            typeStr = "audit";
            templtId = applyTemplateId;
            toUser = auditUser.getOpenId();
            firstStr = "您有一个新的请假申请待审核！";
            remarkStr = "请尽快审核";
            keyStr1 = applyUser.getUserName();
            keyStr4 = dictMapper.selectDictLabel("absence_type",absence.getType());
        }else{
            //结果通知
            typeStr = "show";
            templtId = resultTemplateId;
            String resultStr = "";
            if (absence.getState()==3){
                resultStr = "未通过";
                remarkStr = "不通过";
                color = "#ff0000";
            }else {
                resultStr = "已通过";
                remarkStr = "通过";
            }
            toUser = applyUser.getOpenId();
            firstStr = "您的请假申请"+resultStr+"！";
            keyStr1 = dictMapper.selectDictLabel("absence_type",absence.getType());
        }
        String url = "http://kq.heshenghua.net/office/#/leavespDetail?type="+typeStr+"&openId="+toUser+"&absenceId="+absence.getAbsenceId();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", toUser);   // openid
        jsonObject.put("template_id", templtId);
        jsonObject.put("url", url);

        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", firstStr);
        first.put("color", "#173177");

        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", keyStr1);
        keyword1.put("color", "#173177");

        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", keyStr2);
        keyword2.put("color", "#173177");

        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", keyStr3);
        keyword3.put("color", "#173177");

        JSONObject keyword4 = new JSONObject();
        keyword4.put("value", keyStr4);
        keyword4.put("color", "#173177");

        JSONObject remark = new JSONObject();
        remark.put("value", remarkStr);
        remark.put("color", color);

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        if (type==1){
            data.put("keyword4",keyword4);
        }
        data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
    }

    @Override
    public String getDuration(String startTime, String endTime) {
        //得到开始的小时
        String starHour = startTime.substring(11,16);
        //得到结束的小时
        String endHour = endTime.substring(11,16);
        SimpleDateFormat sdf1 = new SimpleDateFormat("HH:mm");
        TbShift shift = shiftService.selectTbShiftById();
        String start1 = null;
        String end1 = null;
        String start2 = null;
        String end2 = null;
        Long duration1 = 0L;
        Long duration2 = 0L;
        Long workHours = 0L;
        try {
            if (shift!=null){
                start1 = shift.getStartTime1();
                end1 = shift.getEndTime1();
                int num = shift.getNum();
                if (num==4){
                    start2 = shift.getStartTime2();
                    end2 = shift.getEndTime2();
                    duration1=(sdf1.parse(end1).getTime())-(sdf1.parse(start1).getTime());
                    duration2=(sdf1.parse(end2).getTime())-(sdf1.parse(start2).getTime());
                    workHours = duration1+duration2;
                }
            }
            Long  duration = 0L;
            if (DateUtil.isSameDay(startTime,endTime)){
                //开始时间在上午上班前   结束时间在上午下班之前
                if(starHour.compareTo(start1)<=0 && endHour.compareTo(end1)<=0 && endHour.compareTo(start1)>=0){
                    duration = sdf1.parse(endHour).getTime()-sdf1.parse(start1).getTime();
                    //开始时间在上午上班前 && 结束时间在下午上班前
                }else if(starHour.compareTo(start1)<=0 && endHour.compareTo(end1)>0 && endHour.compareTo(start2)<=0){
                    duration=duration1;
                    //开始时间在上午上班前 && 结束时间在下午下班前
                }else if(starHour.compareTo(start1)<=0 && endHour.compareTo(start2)>0 && endHour.compareTo(end2)<=0){
                    duration= workHours-((sdf1.parse(end2).getTime())-(sdf1.parse(endHour).getTime()));
                    //开始时间在上午上班前 && 结束时间在下午下班之后
                }else if(starHour.compareTo(start1)<=0 && endHour.compareTo(end2)>0){
                    duration=workHours;
                    //开始时间在上午上班内 && 结束时间在上午下班前
                }else if(starHour.compareTo(start1)>=0 && starHour.compareTo(end1)<=0 && endHour.compareTo(end1)<=0){
                    duration= ((sdf1.parse(endHour).getTime())-(sdf1.parse(starHour).getTime()));
                    //开始时间在上午上班内 && 结束时间在中午
                }else if(starHour.compareTo(start1)>=0 && starHour.compareTo(end1)<=0 && endHour.compareTo(end1)>0 && endHour.compareTo(start2)<=0){
                    duration=((sdf1.parse(end1).getTime())-(sdf1.parse(starHour).getTime()));
                    //开始时间在上午上班内 && 结束时间在下午
                }else if(starHour.compareTo(start1)>=0 && starHour.compareTo(end1)<=0 && endHour.compareTo(start2)>0 && endHour.compareTo(end2)<=0){
                    duration=((sdf1.parse(end1).getTime())-(sdf1.parse(starHour).getTime()))+((sdf1.parse(endHour).getTime())-(sdf1.parse(start2).getTime()));
                    //开始时间在上午上班内 && 结束时间在下午下班之后
                }else if(starHour.compareTo(start1)>=0 && starHour.compareTo(end1)<=0 && endHour.compareTo(end2)>0){
                    duration= workHours-((sdf1.parse(starHour).getTime())-(sdf1.parse(start1).getTime()));
                    //开始时间在中午 && 结束时间在下午
                }else if(starHour.compareTo(end1)>0 && starHour.compareTo(start2)<=0 && endHour.compareTo(start2)>0 && endHour.compareTo(end2)<=0){
                    duration= ((sdf1.parse(endHour).getTime())-(sdf1.parse(start2).getTime()));
                    //开始时间在中午 && 结束时间在下午下班之后
                }else if(starHour.compareTo(end1)>0 && starHour.compareTo(start2)<=0 && endHour.compareTo(end2)>0){
                    duration= duration2;
                    //开始时间在下午 && 结束时间在下午
                }else if(starHour.compareTo(start2)>0 && starHour.compareTo(end2)<=0 && endHour.compareTo(end2)<=0){
                    duration= ((sdf1.parse(endHour).getTime())-(sdf1.parse(starHour).getTime()));
                    //开始时间在下午 && 结束时间在下午下班之后
                }else if(starHour.compareTo(start2)>0 && starHour.compareTo(end2)<=0 && endHour.compareTo(end2)>0){
                    duration= ((sdf1.parse(end2).getTime())-(sdf1.parse(starHour).getTime()));
                    //其他时间   都在上午上班前   ||  都在中午  ||  都在下午下班之后
                }else{
                    duration=0L;
                }
            }else {
                List<String> dateList = DateUtil.getDays(startTime, endTime);
                for (int i = dateList.size()-1; i >= 0; i--) {
                    Integer type = holidayMapper.getIsHoliday(dateList.get(i));
                    if (i == (dateList.size() - 1)) {
                        if (type==1){
                            //结束在上午上班之前
                            if(endHour.compareTo(start1)<=0){
                                duration += 0L;
                                //结束在上午上班
                            }else if(endHour.compareTo(start1)>0 && endHour.compareTo(end1)<=0){
                                duration += (sdf1.parse(endHour).getTime()-sdf1.parse(start1).getTime());
                                //结束在中午
                            }else if(endHour.compareTo(end1)>0 && endHour.compareTo(start2)<=0){
                                duration += duration1;
                                //结束在下午上班
                            }else if(endHour.compareTo(start2)>0 && endHour.compareTo(end2)<=0){
                                duration += (workHours-(sdf1.parse(end2).getTime()-sdf1.parse(endHour).getTime()));
                            }else if(endHour.compareTo(end2)>0){
                                duration += workHours;
                            }
                        }else{
                            duration += 0L;
                        }
                    }else if(i==0){
                        if (type == 1){
                            //开始在上午上班之前
                            if(starHour.compareTo(start1)<=0){
                                duration += workHours;
                                //开始在上午上班
                            }else if(starHour.compareTo(start1)>0 && starHour.compareTo(end1)<=0){
                                duration += (workHours-(sdf1.parse(starHour).getTime()-sdf1.parse(start1).getTime()));
                                //开始在中午
                            }else if(starHour.compareTo(end1)>0 && starHour.compareTo(start2)<=0){
                                duration += duration2;
                                //开始在下午上班
                            }else if(starHour.compareTo(start2)>0 && starHour.compareTo(end2)<=0){
                                duration += (sdf1.parse(end2).getTime()-sdf1.parse(starHour).getTime());
                                //开始在下午下班之后
                            }else if(starHour.compareTo(end2)>0){
                                duration += 0L;
                            }
                        }else{
                            duration += 0L;
                        }
                        //日期期间
                    }else if(0<i && i<(dateList.size()-1)){
                        if (type==1){
                            duration += workHours;
                        }else {
                            duration += 0L;
                        }
                    }
                }
            }
            String result = new DecimalFormat("0.0").format((float)duration/(1000 * 60 * 60));
            return result;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public TbAbsence getDetail(Long absenceId) {
        return baseMapper.getDetail(absenceId);
    }

    @Override
    public List<TbAbsence> list(AbsenceDto absenceDto) {
        Long userId = SecurityUtils.getUserId();
        absenceDto.setUserId(userId);
        if("approve".equals(absenceDto.getType())){
            return absenceAuditMapper.list(absenceDto);
        }
        return baseMapper.list(absenceDto);
    }

    @Override
    @Transactional
    public int reportBack(TbReportBack reportBack) {
        TbAbsence absence = this.baseMapper.selectById(reportBack.getAbsenceId());
        absence.setState(4);
        absence.setUpdateBy(SecurityUtils.getUsername());
        absence.setUpdateTime(new Date());
        baseMapper.updateById(absence);
        reportBack.setApplyTime(new Date());
        int row = reportBackMapper.insert(reportBack);
        sendReportBackApplyMessage(reportBack);
        return row;
    }

    @Override
    @Transactional
    public int editReportBack(TbReportBack reportBack) {
        if (reportBack.getState()==3){
            this.sendReportBackApplyMessage(reportBack);
        }
        TbAbsence absence = this.baseMapper.selectById(reportBack.getAbsenceId());
        absence.setState(4);
        absence.setUpdateBy(SecurityUtils.getUsername());
        absence.setUpdateTime(new Date());
        baseMapper.updateById(absence);
        reportBack.setState(1);
        reportBack.setApproveReason(null);
        reportBack.setApproveTime(null);
        reportBack.setApplyTime(new Date());
        int row = reportBackMapper.updateById(reportBack);
        sendReportBackApplyMessage(reportBack);
        return row;
    }

    @Override
    public int approveReportBack(TbReportBack reportBack) {
        TbReportBack tbReportBack = reportBackMapper.selectById(reportBack.getId());
        TbAbsence absence = baseMapper.selectById(tbReportBack.getAbsenceId());
        SysUser user = userService.selectUserById(absence.getApplyId());
        if (reportBack.getState()==2){
            if (absence.getSabbaticalHour()!=0d){
                Double actual = absence.getAbsenceDuration()- tbReportBack.getReportBackDuration();
                if (actual==0){
                    user.setOverworkHour(user.getOverworkHour()+absence.getSabbaticalHour());
                    absence.setActualAbsence(0d);
                    absence.setActualSabbatical(0d);
                    //absence.setSabbaticalHour(0d);
                }else if(absence.getSabbaticalHour()>=actual){
                    user.setOverworkHour(user.getOverworkHour()+(absence.getSabbaticalHour()-actual));
                    absence.setActualAbsence(0d);
                    absence.setActualSabbatical(actual);
                    //absence.setSabbaticalHour(actual);
                }else if(absence.getSabbaticalHour()<actual){
                    absence.setActualAbsence(absence.getActualAbsence()- reportBack.getReportBackDuration());
                    //absence.setSabbaticalHour(actual);
                }
                userService.updateUserProfile(user);
            }else {
                absence.setActualAbsence(absence.getAbsenceDuration()-tbReportBack.getReportBackDuration());
            }
            updateAbsence(absence.getApplyId(),tbReportBack.getReportBackTime(),absence.getEndTime());
            absence.setState(5);
        }else {
            absence.setState(6);
        }
        absence.setUpdateBy(SecurityUtils.getUsername());
        absence.setUpdateTime(new Date());
        baseMapper.updateById(absence);
        tbReportBack.setState(reportBack.getState());
        tbReportBack.setApproveTime(new Date());
        tbReportBack.setApproveReason(reportBack.getApproveReason());
        int row = reportBackMapper.updateById(tbReportBack);
        sendReportBackResultMessage(tbReportBack);
        return row;
    }

    @Override
    @Transactional
    public AjaxResult approve(TbAbsenceAudit absenceAudit) {
        TbAbsence absence = baseMapper.selectById(absenceAudit.getAbsenceId());
        absenceAudit.setApproveTime(new Date());
        absenceAuditMapper.updateById(absenceAudit);
        if (absenceAudit.getStatus()==2){
            if (absenceAudit.getNextUserId()!=null){
                TbAbsenceAudit audit = new TbAbsenceAudit();
                audit.setAbsenceId(absence.getAbsenceId());
                audit.setApproveId(absenceAudit.getNextUserId());
                audit.setCreateBy(SecurityUtils.getUsername());
                audit.setCreateTime(new Date());
                absenceAuditMapper.insert(audit);
                this.sendMessage(absence,absenceAudit.getNextUserId(),1);
            }else {
                absence.setState(absenceAudit.getStatus());
                absence.setUpdateBy(SecurityUtils.getUsername());
                absence.setUpdateTime(new Date());
                baseMapper.updateById(absence);
                if (absence.getSabbaticalHour()>0){
                    SysUser applyUser = userService.selectUserById(absence.getApplyId());
                    applyUser.setOverworkHour(applyUser.getOverworkHour()-absence.getSabbaticalHour());
                    userService.updateUserProfile(applyUser);
                }
                this.sendMessage(absence,null,2);
            }
        }else {
            absence.setState(absenceAudit.getStatus());
            absence.setUpdateBy(SecurityUtils.getUsername());
            absence.setUpdateTime(new Date());
            baseMapper.updateById(absence);
            this.sendMessage(absence,null,2);
        }
        return AjaxResult.success();
    }

    public void updateAbsence(Long userId,Date startTime,Date endTime){
        TbShift shift = shiftService.selectTbShiftById();
        String startTime1 = shift.getStartTime1();
        String startTime2 = shift.getStartTime2();
        String endTime1 = shift.getEndTime1();
        String endTime2 = shift.getEndTime2();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("HH:mm");
        List<TbPunchCard> punchCardList = punchCardMapper.getUserPunchCard(userId,sdf.format(startTime),sdf.format(endTime));
        if(endTime1.compareTo(sdf2.format(startTime))>0 && startTime1.compareTo(sdf2.format(startTime))<0){
            TbPunchCard punchCard = punchCardMapper.getPunchCardByStateAndDate(userId,sdf.format(startTime),1);
            punchCardList.remove(punchCard);
        }
        if(startTime2.compareTo(sdf2.format(startTime))>=0 && endTime1.compareTo(sdf2.format(startTime))<=0){
            List<TbPunchCard> punchCardList1 = punchCardMapper.selectList(new QueryWrapper<TbPunchCard>().eq("user_id",userId).eq("DATE(create_time)",sdf.format(startTime)).in("state",1,2));
            if (punchCardList1!=null && punchCardList1.size()>0){
                punchCardList1.forEach(punchCard -> {
                    punchCardList.remove(punchCard);
                });
            }
        }
        if(endTime2.compareTo(sdf2.format(startTime))>0 && startTime2.compareTo(sdf2.format(startTime))<0){
            List<TbPunchCard> punchCardList1 = punchCardMapper.selectList(new QueryWrapper<TbPunchCard>().eq("user_id",userId).eq("DATE(create_time)",sdf.format(startTime)).in("state",1,2,3));
            if (punchCardList1!=null && punchCardList1.size()>0){
                punchCardList1.forEach(punchCard -> {
                    punchCardList.remove(punchCard);
                });
            }
        }
        if(endTime1.compareTo(sdf2.format(endTime))>0 && startTime1.compareTo(sdf2.format(endTime))<0){
            List<TbPunchCard> punchCardList1 = punchCardMapper.selectList(new QueryWrapper<TbPunchCard>().eq("user_id",userId).eq("DATE(create_time)",sdf.format(endTime)).in("state",2,3,4));
            if (punchCardList1!=null && punchCardList1.size()>0){
                punchCardList1.forEach(punchCard -> {
                    punchCardList.remove(punchCard);
                });
            }
        }
        if(startTime2.compareTo(sdf2.format(endTime))>0 && endTime1.compareTo(sdf2.format(endTime))<=0){
            List<TbPunchCard> punchCardList1 = punchCardMapper.selectList(new QueryWrapper<TbPunchCard>().eq("user_id",userId).eq("DATE(create_time)",sdf.format(endTime)).in("state",3,4));
            if (punchCardList1!=null && punchCardList1.size()>0){
                punchCardList1.forEach(punchCard -> {
                    punchCardList.remove(punchCard);
                });
            }
        }
        if(endTime2.compareTo(sdf2.format(endTime))>0 && startTime2.compareTo(sdf2.format(endTime))<0){
            TbPunchCard punchCard = punchCardMapper.getPunchCardByStateAndDate(userId,sdf.format(endTime),4);
            punchCardList.remove(punchCard);
        }

        if (punchCardList!=null && punchCardList.size()>0){
            String startStr = "";
            String endStr = "";
            for (TbPunchCard punchCard : punchCardList) {
                if (punchCard.getStatus()==3){
                    if (punchCard.getState()==1){
                        startStr = sdf.format(punchCard.getCreateTime())+" 06:00:00";
                        endStr = DateUtil.getChangeTime(sdf.format(punchCard.getCreateTime())+" "+shift.getStartTime1()+":00",30);
                        TbAttendanceRecord attendanceRecord = attendanceMapper.selectOne(new QueryWrapper<TbAttendanceRecord>().eq("user_id",punchCard.getDingUserId()).between("date_format(user_check_time,'%Y-%m-%d %H:%i:%S')",startStr,endStr).orderByAsc("user_check_time").last("limit 1"));
                        if (attendanceRecord!=null){
                            if (shift.getStartTime1().compareTo(sdf2.format(attendanceRecord.getUserCheckTime()))>=0) {
                                punchCard.setStatus(4);

                            }else {
                                punchCard.setStatus(2);
                            }
                            punchCard.setPunchCardTime(attendanceRecord.getUserCheckTime());
                            punchCard.setPunchCardType(attendanceRecord.getSourceType());
                            punchCard.setAddress(attendanceRecord.getAddress());
                            punchCard.setAttendanceId(attendanceRecord.getId());
                        }else {
                            punchCard.setStatus(1);
                        }
                    }else if (punchCard.getState()==2){
                        startStr = sdf.format(punchCard.getCreateTime())+" "+shift.getEndTime1()+":00";
                        endStr = DateUtil.getChangeTime(sdf.format(punchCard.getCreateTime())+" "+shift.getEndTime1()+":00",30);
                        TbAttendanceRecord attendanceRecord = attendanceMapper.selectOne(new QueryWrapper<TbAttendanceRecord>().eq("user_id",punchCard.getDingUserId()).between("date_format(user_check_time,'%Y-%m-%d %H:%i:%S')",startStr,endStr).orderByAsc("user_check_time").last("limit 1"));
                        if (attendanceRecord!=null){
                            punchCard.setStatus(4);
                            punchCard.setPunchCardTime(attendanceRecord.getUserCheckTime());
                            punchCard.setPunchCardType(attendanceRecord.getSourceType());
                            punchCard.setAddress(attendanceRecord.getAddress());
                            punchCard.setAttendanceId(attendanceRecord.getId());
                        }else {
                            punchCard.setStatus(1);
                        }
                    }else if (punchCard.getState()==3){
                        startStr = DateUtil.getChangeTime(sdf.format(punchCard.getCreateTime())+" "+shift.getStartTime2()+":00",-30);
                        endStr = DateUtil.getChangeTime(sdf.format(punchCard.getCreateTime())+" "+shift.getStartTime2()+":00",30);
                        TbAttendanceRecord attendanceRecord = attendanceMapper.selectOne(new QueryWrapper<TbAttendanceRecord>().eq("user_id",punchCard.getDingUserId()).between("date_format(user_check_time,'%Y-%m-%d %H:%i:%S')",startStr,endStr).orderByAsc("user_check_time").last("limit 1"));
                        if (attendanceRecord!=null){
                            if (shift.getStartTime2().compareTo(sdf2.format(attendanceRecord.getUserCheckTime()))>=0) {
                                punchCard.setStatus(4);
                            }else {
                                punchCard.setStatus(2);
                            }
                            punchCard.setPunchCardTime(attendanceRecord.getUserCheckTime());
                            punchCard.setPunchCardType(attendanceRecord.getSourceType());
                            punchCard.setAddress(attendanceRecord.getAddress());
                            punchCard.setAttendanceId(attendanceRecord.getId());
                        }else {
                            punchCard.setStatus(1);
                        }
                    }else {
                        startStr = sdf.format(punchCard.getCreateTime())+" "+shift.getEndTime2()+":00";
                        TbAttendanceRecord attendanceRecord = attendanceMapper.selectOne(new QueryWrapper<TbAttendanceRecord>().eq("user_id",punchCard.getDingUserId()).eq("date(work_date)",sdf.format(punchCard.getCreateTime())).ge("date_format(user_check_time,'%Y-%m-%d %H:%i:%S')",startStr).orderByAsc("user_check_time").last("limit 1"));
                        if (attendanceRecord!=null){
                            punchCard.setStatus(4);
                            punchCard.setPunchCardTime(attendanceRecord.getUserCheckTime());
                            punchCard.setPunchCardType(attendanceRecord.getSourceType());
                            punchCard.setAddress(attendanceRecord.getAddress());
                            punchCard.setAttendanceId(attendanceRecord.getId());
                        }else {
                            punchCard.setStatus(1);
                        }
                    }
                    punchCardMapper.updateById(punchCard);
                }
            }
        }
    }

    public void sendReportBackApplyMessage(TbReportBack reportBack){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        TbAbsence absence = this.baseMapper.selectById(reportBack.getAbsenceId());
        SysUser applyUser = userService.selectUserById(absence.getApplyId());
        SysUser auditUser = userService.selectUserById(absence.getApproveId());
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", auditUser.getOpenId());   // openid
        jsonObject.put("template_id", reportBackApply);
        jsonObject.put("url", "http://kq.heshenghua.net/office/#/leavespDetail?openId="+auditUser.getOpenId()+"&absenceId="+absence.getAbsenceId());

        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        first.put("value", "您有一个新的销假申请待审核！");
        first.put("color", "#173177");
        //申请人
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", applyUser.getUserName());
        keyword1.put("color", "#173177");
        //申请时间
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", sdf.format(reportBack.getApplyTime()));
        keyword2.put("color", "#173177");
        //销假原因
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", reportBack.getReportBackReason());
        keyword3.put("color", "#173177");

        JSONObject remark = new JSONObject();
        remark.put("value", "请尽快审核");
        remark.put("color", "#173177");

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
    }

    /**
     * 修改请假申请
     * @param absence
     * @return
     */
    @Override
    @Transactional
    public AjaxResult edit(TbAbsence absence){
        TbAbsence oldAbsence = baseMapper.selectById(absence.getAbsenceId());
        if (oldAbsence.getApproveId()!=absence.getApproveId()) {
            TbAbsenceAudit audit = absenceAuditMapper.selectOne(new QueryWrapper<TbAbsenceAudit>().eq("absence_id", absence.getAbsenceId()).eq("status",1));
            audit.setApproveId(absence.getApproveId());
            audit.setUpdateBy(SecurityUtils.getUsername());
            audit.setUpdateTime(new Date());
            absenceAuditMapper.updateById(audit);
            this.sendMessage(absence,absence.getApproveId(),1);
        }
        absence.setUpdateTime(new Date());
        absence.setActualAbsence(absence.getAbsenceDuration()-absence.getSabbaticalHour());
        absence.setActualSabbatical(absence.getSabbaticalHour());
        this.updateById(absence);
        return AjaxResult.success();
    }

    public void sendReportBackResultMessage(TbReportBack reportBack){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        TbAbsence absence = this.baseMapper.selectById(reportBack.getAbsenceId());
        SysUser applyUser = userService.selectUserById(absence.getApplyId());
        SysUser auditUser = userService.selectUserById(absence.getApproveId());
        String accessUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+APPID+"&secret="+APPSECRET;
        JSONObject result = WebUtil.doGet(accessUrl);
        String accessToken = null;
        if (null != result) {
            accessToken = result.getString("access_token");
        }
        String templtUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("touser", applyUser.getOpenId());   // openid
        jsonObject.put("template_id", reportBackResult);
        jsonObject.put("url", "http://kq.heshenghua.net/office/#/leavespDetail?openId="+auditUser.getOpenId()+"&absenceId="+absence.getAbsenceId());

        JSONObject data = new JSONObject();
        JSONObject first = new JSONObject();
        String resultStr = "";
        if (reportBack.getState()==2){
            resultStr = "您的销假申请已通过";
        }else if(reportBack.getState()==3){
            resultStr = "您的销假申请未通过";
        }
        first.put("value", resultStr);
        first.put("color", "#173177");
        //开始时间
        JSONObject keyword1 = new JSONObject();
        keyword1.put("value", sdf.format(absence.getStartTime()));
        keyword1.put("color", "#173177");
        //销假时间
        JSONObject keyword2 = new JSONObject();
        keyword2.put("value", sdf.format(reportBack.getReportBackTime()));
        keyword2.put("color", "#173177");
        //审批人
        JSONObject keyword3 = new JSONObject();
        keyword3.put("value", auditUser.getName());
        keyword3.put("color", "#173177");

        JSONObject remark = new JSONObject();
        remark.put("value", "点击查看详情");
        remark.put("color", "#173177");

        data.put("first",first);
        data.put("keyword1",keyword1);
        data.put("keyword2",keyword2);
        data.put("keyword3",keyword3);
        data.put("remark",remark);

        jsonObject.put("data", data);

        String string = null;
        try {
            string = WebUtil.sendPostJsonStr(templtUrl, jsonObject.toJSONString());
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject result1 = JSONObject.parseObject(string);
        int errcode = result1.getIntValue("errcode");
        if(errcode == 0){
            // 发送成功
            System.out.println("发送成功");
        } else {
            // 发送失败
            System.out.println("发送失败");
        }
    }
}
